package com.lzh.es.config;

import com.lzh.es.properties.EsProperties;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import java.util.Arrays;

/**
 * @author zhehen.lu
 * @date 2025/8/14 13:42
 */
@Configuration
public class EsConfig {
    @Autowired
    private EsProperties esProperties;
    public static final RequestOptions COMMON_OPTIONS;

    public EsConfig() {
    }

    @Bean
    @ConditionalOnMissingBean
    public RestHighLevelClient restHighLevelClient() {
        RestClientBuilder builder;
        if (!StringUtils.isEmpty(this.esProperties.getNodes())) {
            HttpHost[] httpHosts = (HttpHost[]) Arrays.stream(this.esProperties.getNodes().split(",")).filter((node) -> {
                return !StringUtils.isEmpty(node);
            }).filter((node) -> {
                String[] split = node.split(":");
                return split.length == 2;
            }).map((node) -> {
                String[] split = node.split(":");
                return new HttpHost(split[0], Integer.valueOf(split[1]), this.esProperties.getSchema());
            }).toArray((x$0) -> {
                return new HttpHost[x$0];
            });
            builder = RestClient.builder(httpHosts);
        } else {
            HttpHost httpHost = new HttpHost(this.esProperties.getHost(), this.esProperties.getPort(), this.esProperties.getSchema());
            builder = RestClient.builder(new HttpHost[]{httpHost});
        }

        builder.setRequestConfigCallback((requestBuilder) -> {
            requestBuilder.setConnectTimeout(this.esProperties.getConnectTimeout());
            requestBuilder.setSocketTimeout(this.esProperties.getSocketTimeout());
            requestBuilder.setConnectionRequestTimeout(this.esProperties.getConnectRequestTimeout());
            return requestBuilder;
        });
        builder.setHttpClientConfigCallback((httpClientBuilder) -> {
            if (!StringUtils.isEmpty(this.esProperties.getUsername())) {
                BasicCredentialsProvider basicCredentialsProvider = new BasicCredentialsProvider();
                basicCredentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(this.esProperties.getUsername(), this.esProperties.getPassword()));
                httpClientBuilder.setDefaultCredentialsProvider(basicCredentialsProvider);
            }

            httpClientBuilder.setMaxConnTotal(this.esProperties.getMaxConnectNum());
            httpClientBuilder.setMaxConnPerRoute(this.esProperties.getMaxConnectPerRoute());
            httpClientBuilder.setKeepAliveStrategy((httpResponse, httpContext) -> {
                return (long)this.esProperties.getKeepAliveTime();
            });
            return httpClientBuilder;
        });
        RestHighLevelClient client = new RestHighLevelClient(builder);
        return client;
    }

    static {
        COMMON_OPTIONS = RequestOptions.DEFAULT.toBuilder().build();
    }
}
